import { BattleStatus, BuildingType, CommandType, EntityType, PlayerType, TildeType, UnitType } from './Enums';

/**
 * 地块模型
 */
export type TildeModel = {
    type: TildeType;
    building?: number;
    unit?: number;
    player?: string;
};

/**
 * 单位模型
 */
export type UnitModel = {
    /**单位id */
    id: number;
    /**单位类型 */
    type: UnitType;
    /**单位所属玩家 */
    player: string;
    /**血量 */
    hp: number;
    /**攻击 */
    attack: number;
    /**速度 */
    speed: number;
    /**位置 */
    position: {
        x: number;
        y: number;
    };
};

/**
 * 建筑模型
 */
export type BuildingModel = {
    /**建筑id */
    id: number;
    /**建筑类型 */
    type: BuildingType;
    /**建筑所属玩家 */
    player: string;
    /**建筑血量 */
    hp: number;
    /**攻击 */
    attack: number;
    /**位置 */
    position: {
        x: number;
        y: number;
    };
};

/**
 * 事件模型
 */
export type EventModel = {
    type: string;
    msg: string;
};

/**
 * 玩家统计数据模型
 */
export type PlayerStatsModel = {
    /** 玩家ID */
    player: string;
    /** 玩家资源（人民币） */
    rmb: number;
    /** 基地血量 */
    baseHealth: number;
    /** 击杀数 */
    kills: number;
    /** 死亡数 */
    deaths: number;
    /** 造成的总伤害 */
    totalDamageDealt: number;
    /** 受到的总伤害 */
    totalDamageReceived: number;
    /** 治疗总量 */
    totalHealing: number;
    /** 命令失败次数 */
    commandFailCount: number;
};

/**
 * 战斗结果数据结构
 */
export type BattleResultData = {
    /** 胜利方玩家ID */
    winner: string | null;
    /** 失败方玩家ID */
    loser: string | null;
    /** 结束消息 */
    msg: string;
    /** 战斗统计数据 */
    playerStats: { [key: string]: PlayerStatsModel };
    /** 失败命令统计 */
    failedCommands?: { [key: string]: FailCommandModel[] };
};

export type FailCommandModel = {
    /** 错误消息*/
    error: string;
    /** 命令数据 */
    command: CommandParam<keyof CommandParamMap>;
    /** 玩家ID */
    player: string;
    /** 回合数 */
    round: number;
    /** 命令类型 */
    type: CommandType;
};

/** 实体执行后状态 */
export type EntityExecutionState = {
    /** 实体ID */
    id: number;
    /** 实体名称 */
    name: string;
    /** 实体位置 */
    position: {
        x: number;
        y: number;
    };
    /** 实体血量 */
    hp: number;
};

/** 命令执行详情模型 */
export type CommandExecutionDetailModel = {
    /** 命令数据 */
    command: CommandParam<keyof CommandParamMap>;
    /** 玩家ID */
    player: string;
    /** 回合数 */
    round: number;
    /** 命令类型 */
    type: CommandType;
    /** self实体执行后状态（如果命令包含self） */
    selfExecutionState?: EntityExecutionState;
    /** target实体执行后状态（如果命令包含target） */
    targetExecutionState?: EntityExecutionState;
    /** 是否执行失败 */
    isError: boolean;
    /** 错误消息，如果为空字符串则表示执行成功 */
    error: string;
};

export type InitCommandParam = {
    /** 地图名字*/
    map: string;
    /** 玩家列表 */
    players: string[];
    /** 最大回合数限制 */
    round_limit?: number;
};

/**
 * {
 *  "self":{"type":0,"utype":4,"id":1},
 *  "offsetPosition":{"x":1,"y":0}
 * }
 */
export type MoveCommandParam = {
    /** 进行移动的单位 */
    self: {
        /** 实体类型 */
        type: EntityType.unit;
        /** 单位类型 */
        utype: UnitType;
        /** 单位ID */
        id: number;
    };
    /** 移动位置差值（相对于当前单位位置的偏移量，即offsetPosition） */
    offsetPosition: {
        x: number;
        y: number;
    };
};

/**
 * {
 *  "self":{"type":0,"utype":3,"id":55},
 *  "target":{"type":0,"utype":0,"id":22},
 *  "offsetPosition":{"x":1,"y":0}
 * }
 */
export type AttackCommandParam = {
    /** 进行攻击的单位 */
    self: {
        /** 实体类型 */
        type: EntityType.unit | EntityType.building;
        /** 单位或建筑类型 */
        utype: UnitType | BuildingType;
        /** 单位或建筑ID */
        id: number;
    };
    /** 攻击目标 */
    target: {
        /** 目标实体类型 */
        type: EntityType.unit | EntityType.building;
        /** 目标单位或建筑类型 */
        utype: UnitType | BuildingType;
        /** 目标ID */
        id: number;
    };
    /** 攻击位置差值（相对于当前单位位置的偏移量，即offsetPosition）*/
    offsetPosition: {
        x: number;
        y: number;
    };
};

/**
 * {
 *  "self":{"type":0,"utype":4,"id":10},
 *  "target":{"type":1,"utype":2,"id":18},
 *  "offsetPosition":{"x":1,"y":0}
 * }
 */
export type BuildCommandParam = {
    /** 进行建造的单位 */
    self: {
        /** 实体类型 */
        type: EntityType.unit;
        /** 单位类型 */
        utype: UnitType;
        /** 单位ID */
        id: number;
    };
    /** 建造目标 */
    target: {
        /** 目标实体类型 */
        type: EntityType.building;
        /** 建筑类型 */
        utype: BuildingType;
        /** 建筑ID */
        id: number;
    };
    /** 建造位置差值（相对于当前建造兵位置的偏移量，即offsetPosition）*/
    offsetPosition: {
        x: number;
        y: number;
    };
};

/**
 * {
 *  "self":{"type":1,"utype":0,"id":1},
 *  "target":{"type":0,"utype":4,"id":1},
 *  "offsetPosition":{"x":-1,"y":6}
 * }
 */
export type SwapCommandParam = {
    /** 进行生产的建筑 */
    self: {
        /** 实体类型 */
        type: EntityType.building;
        /** 建筑类型 */
        utype: BuildingType;
        /** 建筑ID */
        id: number;
    };
    /** 生产的单位 */
    target: {
        /** 目标实体类型 */
        type: EntityType.unit;
        /** 单位类型 */
        utype: UnitType;
        /** 单位ID */
        id: number;
    };
    /** 生产位置差值（相对于当前基地位置的偏移量，即offsetPosition）*/
    offsetPosition: {
        x: number;
        y: number;
    };
};

export type EndCommandParam = {
    /** 战斗结果 */
    result: BattleResultData;
};

/**
 * {
 *  "self":{"type":0,"utype":2,"id":50},
 *  "target":{"type":0,"utype":0,"id":30},
 *  "offsetPosition":{"x":0,"y":-1}
 * }
 */
export type HealCommandParam = {
    /** 进行治疗的单位 */
    self: {
        /** 实体类型 */
        type: EntityType.unit;
        /** 单位类型 */
        utype: UnitType.doctor;
        /** 单位ID */
        id: number;
    };
    /** 治疗目标 */
    target: {
        /** 目标实体类型 */
        type: EntityType.unit;
        /** 目标单位类型 */
        utype: UnitType;
        /** 目标ID */
        id: number;
    };
    /** 治疗位置差值（相对于治疗兵位置的偏移量，即offsetPosition）*/
    offsetPosition: {
        x: number;
        y: number;
    };
};

/**
 * {
 *  "self":{"type":0,"utype":1,"id":11},
 *  "target":{"type":2,"utype":12,"id":0},
 *  "offsetPosition":{"x":1,"y":0}
 * }
 */
export type CollectCommandParam = {
    /** 采集的单位 */
    self: {
        /** 实体类型 */
        type: EntityType.unit;
        /** 单位类型 */
        utype: UnitType.collect;
        /** 单位ID */
        id: number;
    };
    /** 采集目标 */
    target: {
        /** 目标实体类型 */
        type: EntityType.terrain;
        /** 资源类型 */
        utype: TildeType;
        /** 资源ID */
        id: number;
    };
    /** 采集位置差值（相对于采集兵位置的偏移量，即offsetPosition）*/
    offsetPosition: {
        x: number;
        y: number;
    };
};

/**
 * 命令参数映射类型
 * 为每种命令类型定义特定的参数结构
 */
export type CommandParamMap = {
    [CommandType.init]: InitCommandParam;
    [CommandType.end]: EndCommandParam;
    [CommandType.move]: MoveCommandParam;
    [CommandType.attack]: AttackCommandParam;
    [CommandType.build]: BuildCommandParam;
    [CommandType.swap]: SwapCommandParam;
    [CommandType.heal]: HealCommandParam;
    [CommandType.collect]: CollectCommandParam;
};

/**
 * 使用映射类型简化命令参数
 * {
 *  "player":"xxx",
 *  "type":"move",
 *  "round":51,
 *  "param":{
 *          "self":{"type":0,"utype":4,"id":5},
 *          "offsetPosition":{"x":0,"y":1}}
 *          }
 */
export type CommandParam<T extends keyof CommandParamMap> = {
    /** 命令类型 */
    type: T;
    /** 执行的玩家 */
    player: string;
    /** 回合数 */
    round: number;
    /** 命令参数 */
    param: CommandParamMap[T];
};

/**
 * 回合每个玩家命令执行结果
 */
export type RoundProcessResult = {
    /** 回合数 */
    round: number;
    /** 是否处理成功 */
    success: boolean;
    /** 战斗是否结束 */
    battleEnded: boolean;
    /** 结束命令（当战斗结束时） */
    endCommand?: CommandParam<CommandType.end>;
    /** 当前玩家的命令执行详情 */
    playerCommandExecutionDetails: CommandExecutionDetailModel[];
};

/**
 * 索引实体统计项数据
 */
export type IndexEntityStatsItemData = {
    entityId: number;
    playerID: string;
    entityType: EntityType;
    playerType: PlayerType;
};

/**
 * 战斗中状态缓存模型
 */
export type BattleMemModel = {
    /** 战斗状态 */
    status: BattleStatus;
    /** 玩家列表 */
    players: string[];
    /** 战斗结果 */
    battleResult: BattleResultData | null;
    /** 当前回合数 */
    currentRound: number;
    /** 当前回合命令 */
    currentRoundCommands: { [key: string]: CommandParam<keyof CommandParamMap>[] };
    /** 当前回合已执行的实体集合 */
    currentRoundEntities: Set<string>;
    /** 当前回合新生产的实体集合 */
    currentRoundNewEntities: Set<string>;
};

/**
 * 玩家信息模型
 */
export type PlayerInfoModel = {
    /** 玩家ID */
    id: string;
    /** 玩家类型 */
    playerType: string;
    /** 玩家金钱 */
    rmb: number;
    /** 玩家基地血量 */
    baseHealth: number;
    /** 玩家单位 */
    units: UnitModel[];
    /** 玩家建筑 */
    buildings: BuildingModel[];
    /** 玩家统计信息 */
    stats: {
        kills: number;
        deaths: number;
        totalDamageDealt: number;
        totalDamageReceived: number;
        totalHealing: number;
        commandFailCount: number;
    };
};

/**
 * 完整游戏状态模型
 */
export type GameStateModel = {
    /** 状态标识 */
    status: string;
    /** 是否已初始化 */
    initialized: boolean;
    /** 战斗是否结束 */
    battleEnded: boolean;
    /** 当前回合数 */
    currentRound: number;
    /** 玩家信息 */
    players: { [playerId: string]: PlayerInfoModel };
    /** 地图数据 */
    map: {
        width: number;
        height: number;
        terrain: TildeModel[][];
    };
    /** 战斗结果 */
    battleResult: BattleResultData | null;
};
